﻿namespace JoinBox.CAD;

public static class AcadRegistry
{
    /// <summary>
    /// 修复注册表
    /// 这个函数功能就是在重置之后,不重启cad而创建文档不会致命错误<br/>
    /// Acad08重置之后,新建文档会致命错误<br/>
    /// 重置cad会清理注册表,这个时候新建图纸就会致命错误(即使是自带的ctrl+n操作)<br/>
    /// 所以这个时候导出-用户配置注册表-是缺失的<br/>
    /// 重启cad之后,会自动补充这部分注册表,这个时候是完整的(另存为图纸也可以实现,就是完全关闭掉所有文档则没法另存)<br/>
    /// 两份注册表就可以用来对比<br/>
    /// </summary>
    public static void RepairRegistry()
    {
        bool writable = true;
        // 通过注册表获取上次另存为的路径
        var cprofile = Env.GetVar("cprofile"); // 当前用户配置的名称

#if NET35
        string key = HostApplicationServices.Current.RegistryProductRootKey; // 这里浩辰读出来是""
#elif !HC2020
        string key = HostApplicationServices.Current.UserRegistryProductRootKey;
#endif
        var currentUser = Registry.CurrentUser.OpenSubKey(key, writable);

        // 注册表_当前配置
        var regedit_Cprofile = currentUser.CreateSubKey($"Profiles\\{cprofile}");

        // 注册表_
        var regedit_Dialogs = regedit_Cprofile.CreateSubKey("Dialogs");
        {
            var acDim_DimstyleFormat = regedit_Dialogs.CreateSubKey("AcDim:DimstyleFormat");
            {
                ChangReg(acDim_DimstyleFormat, "ActiveTab", 0, RegistryValueKind.DWord);
            }

            var allAnavDialogs = regedit_Dialogs.CreateSubKey("AllAnavDialogs");
            {
                ChangReg(allAnavDialogs, "PlacesOrder0", "History");
                ChangReg(allAnavDialogs, "PlacesOrder0Display", "历史记录");
                ChangReg(allAnavDialogs, "PlacesOrder0Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder1", "Personal");
                ChangReg(allAnavDialogs, "PlacesOrder1Display", "文档");
                ChangReg(allAnavDialogs, "PlacesOrder1Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder2", "Favorites");
                ChangReg(allAnavDialogs, "PlacesOrder2Display", "收藏夹");
                ChangReg(allAnavDialogs, "PlacesOrder2Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder3", "FTPSites");
                ChangReg(allAnavDialogs, "PlacesOrder3Display", "FTP");
                ChangReg(allAnavDialogs, "PlacesOrder3Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder4", "Desktop");
                ChangReg(allAnavDialogs, "PlacesOrder4Display", "桌面");
                ChangReg(allAnavDialogs, "PlacesOrder4Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder5", "ACPROJECT");
                ChangReg(allAnavDialogs, "PlacesOrder5Display", "Buzzsaw");
                ChangReg(allAnavDialogs, "PlacesOrder5Ext", string.Empty);

                ChangReg(allAnavDialogs, "PlacesOrder6", string.Empty);
            }

            string[] cus = { "CustomizeDialog", "DrawingSettingsDialog", "OptionsDialog" };
            foreach (var item in cus)
            {
                var cu = regedit_Dialogs.CreateSubKey(item + "\\TabExtensions");
                ChangReg(cu, "acmgd.dll", "acmgd.dll");
            }

            var xzyb = regedit_Dialogs.CreateSubKey("选择样板");
            {
                var templatePath = Env.GetEnv("TemplatePath");// 模板路径

                ChangReg(xzyb, "InitialFilterIndex", 0x00000000, RegistryValueKind.DWord);
                ChangReg(xzyb, "ViewMode", 0x00000004, RegistryValueKind.DWord);

                ChangReg(xzyb, "InitialDirectory", templatePath + "\\", RegistryValueKind.String);

                ChangReg(xzyb, "PreviewVisible", 0x00000001, RegistryValueKind.DWord);
                ChangReg(xzyb, "X", 0x00000226, RegistryValueKind.DWord);
                ChangReg(xzyb, "Y", 0x00000158, RegistryValueKind.DWord);

                ChangReg(xzyb, "Width", 0x00000283, RegistryValueKind.DWord);
                ChangReg(xzyb, "Height", 0x000001a1, RegistryValueKind.DWord);
            }
        }

        // 注册表_Dialogs_Window
        var regedit_Drawing_Window = regedit_Cprofile.CreateSubKey("Drawing Window");
        {
            ChangReg(regedit_Drawing_Window, "SDIMode", 0, RegistryValueKind.DWord);
        }

        // 注册表_Editor_Configuration
        var regedit_Editor_Configuration = regedit_Cprofile.CreateSubKey("Editor Configuration");
        {
            // "CustomDictionary" = "C:\\Users\\LQH\\AppData\\Roaming\\Autodesk\\AutoCAD 2008\\R17.1\\chs\\support\\sample.cus"
            // 这里没有设置好,但是也没有关系,不报错就行.
            ChangReg(regedit_Editor_Configuration, "CustomDictionary", "", RegistryValueKind.String);
            ChangReg(regedit_Editor_Configuration, "MainDictionary", "enu", RegistryValueKind.String);
            ChangReg(regedit_Editor_Configuration, "MTextEditor", "内部", RegistryValueKind.String);

            var temp = Path.GetTempPath();
            ChangReg(regedit_Editor_Configuration, "SaveFilePath", temp, RegistryValueKind.String);
            ChangReg(regedit_Editor_Configuration, "XrefLoadPath", temp, RegistryValueKind.String);
        }

        // 注册表_General
        var regedit_General = regedit_Cprofile.CreateSubKey("General");
        {
            ChangReg(regedit_General, "ACET-ACETMAIN-MENULOADED", "1", RegistryValueKind.String);
            ChangReg(regedit_General, "Anyport", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Attdia", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Attreq", 1, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Blipmode", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Coords", 1, RegistryValueKind.DWord);

            // try
            // {
            //     ChangReg(regedit_General, "Delobj", 0xffffffff, RegistryValueKind.DWord);// 这句会报错,不设置可以
            // }
            // catch (Exception e)
            // {
            //    throw e;
            // }

            ChangReg(regedit_General, "Dragmode", 2, RegistryValueKind.DWord);
            ChangReg(regedit_General, "HideSystemPrinters", 0, RegistryValueKind.DWord);

            ChangReg(regedit_General, "LayerPMode", "1", RegistryValueKind.String);
            ChangReg(regedit_General, "MRUConfig", "Adobe PDF", RegistryValueKind.String);

            ChangReg(regedit_General, "OLEQUALITY", 3, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Osmode", 0x00001025, RegistryValueKind.DWord);
            ChangReg(regedit_General, "PAPERUPDATE", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Pickstyle", 1, RegistryValueKind.DWord);
            ChangReg(regedit_General, "PLOTLEGACY", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "PLSPOOLALERT", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "PSTYLEPOLICY", 1, RegistryValueKind.DWord);
            ChangReg(regedit_General, "RASTERTHRESHOLD", 0x14, RegistryValueKind.DWord);
            ChangReg(regedit_General, "RASTERPERCENT", 0x14, RegistryValueKind.DWord);
            ChangReg(regedit_General, "UseMRUConfig", 0, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Validation Policy", 0x3, RegistryValueKind.DWord);
            ChangReg(regedit_General, "Validation Strategy", 0x1, RegistryValueKind.DWord);
        }
        // 注册表_
        var regedit_MLeader = regedit_Cprofile.CreateSubKey("MLeader");
        {
            ChangReg(regedit_MLeader, "", "", RegistryValueKind.String);// 这种是默认吗???
            ChangReg(regedit_MLeader, "CreatedMode", 1, RegistryValueKind.DWord);
        }
        // 注册表_
        var regedit_Previous_plot_settings = regedit_Cprofile.CreateSubKey("Previous plot settings");
        {
            regedit_Previous_plot_settings.CreateSubKey("Layout");
            regedit_Previous_plot_settings.CreateSubKey("Model");
        }
        // 注册表_
        var regedit_StatusBar = regedit_Cprofile.CreateSubKey("StatusBar");
        {
            var regedit_Application = regedit_StatusBar.CreateSubKey("Application");
            ChangReg(regedit_Application, "AnnotationScales", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "AnnotationVisibility", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "AutoScale", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "CleanScreenPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "CursorCoordinatesPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "DynamicUCSPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "DynInputPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "FloatPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "GridPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "LayoutIconPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "LayoutMoreIconPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "LineweightPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "ModelIconPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "OrthoPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "OSnapPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "OTrackPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "Paper/ModelPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "PolarPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "SnapPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "SpacerPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "TabletPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "ViewportLockState", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "ViewportScales", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "VpMaxPrevPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "VpMaxPane", 1, RegistryValueKind.DWord);
            ChangReg(regedit_Application, "VpMaxNextPane", 1, RegistryValueKind.DWord);
        }
    }

    /// <summary>
    /// 如果注册表没有这个值才加入,否则就不加入
    /// </summary>
    /// <param name="regedit"></param>
    /// <param name="name"></param>
    /// <param name="value"></param>
    /// <param name="kind"></param>
    private static void ChangReg(RegistryKey regedit,
                                 string name,
                                 object value,
                                 RegistryValueKind kind = RegistryValueKind.String)
    {
        if (!regedit.GetValueNames().Contains(name))
            regedit.SetValue(name, value, kind);
    }
}

public class AcadRegeditCproFile
{
    public class Place
    {
        /// <summary>
        /// 路径
        /// </summary>
        public string? Path;
        public string? PathValue;
        /// <summary>
        /// 显示描述
        /// </summary>
        public string? Display;
        public string? DisplayValue;
        /// <summary>
        /// 环境变量
        /// </summary>
        public string? Ext;
        public string? ExtValue;
    }

    public List<Place> Places = new();
    readonly RegistryKey _allAnavDialogs;

    /// <summary>
    /// 读取cad注册表的配置文件中所有的另存为暂存路径
    /// </summary>
    /// <param name="writable"></param>
    public AcadRegeditCproFile(bool writable = true)
    {
        AcadRegistry.RepairRegistry();

        // 通过注册表获取上次另存为的路径
        var cprofile = Env.GetVar("cprofile"); // 当前用户配置的名称

#if NET35
        string key = HostApplicationServices.Current.RegistryProductRootKey; // 这里浩辰读出来是""
#elif !HC2020
        string key = HostApplicationServices.Current.UserRegistryProductRootKey;
#endif
        var dialogs = Registry.CurrentUser.OpenSubKey(key, writable);
        dialogs = dialogs.CreateSubKey($"Profiles\\{cprofile}\\Dialogs");

        _allAnavDialogs = dialogs.CreateSubKey("AllAnavDialogs");
        foreach (var pl in _allAnavDialogs.GetValueNames())
        {
            if (!Regex.IsMatch(pl, @"^PlacesOrder\d$"))
                continue;

            // 获取末尾的数字
            var match = new Regex(@"(\d+)$").Match(pl);
            var num = match.Groups[match.Length - 1].Value;

            var place = new Place
            {
                Path = pl,
                PathValue = _allAnavDialogs.GetValue(pl)?.ToString()
            };
            foreach (var item in _allAnavDialogs.GetValueNames())
            {
                if (item == $"PlacesOrder{num}Display")
                {
                    place.Display = item;
                    place.DisplayValue = _allAnavDialogs.GetValue(item)?.ToString();
                }
                else if (item == $"PlacesOrder{num}Ext")
                {
                    place.Ext = item;
                    place.ExtValue = _allAnavDialogs.GetValue(item)?.ToString();
                }
            }
            Places.Add(place);
        }
    }

    /// <summary>
    /// 储存路径
    /// </summary>
    public void Save(string path)
    {
        _allAnavDialogs.SetValue("PlacesOrder0", path);
    }
}